using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;
using Microsoft.Surface;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using System.Timers;
using System.Diagnostics;

namespace BaseAttack
{
    /// <summary>
    /// Interaction logic for SurfaceWindow1.xaml
    /// </summary>
    public partial class SurfaceWindow1 : SurfaceWindow
    {
        private List<Unit> Units = new List<Unit>();
        private List<Target> Targets = new List<Target>();
        private List<Factory> Factories = new List<Factory>();
        private int Cash = 1600;

        private Timer Time = new Timer();
        private Stopwatch RealTime = new Stopwatch();
        private double MSPerTick = 10;

        // --------------------------- CONSTRUCTOR -----------------------
        public SurfaceWindow1()
        {
            InitializeComponent();

            // Add handlers for Application activation events
            AddActivationHandlers();

            this.Loaded += new RoutedEventHandler(SurfaceWindow1_Loaded);
            this.ContactDown += new ContactEventHandler(SurfaceWindow1_ContactDown);
            this.ContactChanged += new ContactEventHandler(SurfaceWindow1_ContactChanged);
            this.ContactUp += new ContactEventHandler(SurfaceWindow1_ContactUp);

            Time.Interval = MSPerTick;
            Time.AutoReset = true;
            Time.Enabled = true;
            Time.Elapsed += new ElapsedEventHandler(Time_Elapsed);
            RealTime.Start();
        }

        // --------------------------- ENGINE TIMER -----------------------
        void Time_Elapsed(object sender, ElapsedEventArgs e)
        {
            this.Dispatcher.Invoke(new ElapsedEventHandler(Time_Elapsed_LocalThread), sender, e);
        }
        void Time_Elapsed_LocalThread(object sender, ElapsedEventArgs e)
        {
            double RealMS = RealTime.ElapsedMilliseconds / MSPerTick;
            RealTime.Reset();
            RealTime.Start();

            UI.BeginInit();

            // Units
            foreach (Unit u in Units)
            {
                u.Tick(RealMS, Targets);
            }

            // Targets
            Boolean Won = true;
            foreach (Target t in Targets)
            {
                if (t.Alive) Won = false;
            }
            if (Won)
            {
                Time.Enabled = false;
                MessageBox.Show("You Win!");
                this.Close();
            }
            UI.EndInit();

        }

        // --------------------------- GLOBAL STUFF -----------------------
        public void UpdateCash(int NewCash)
        {
            Cash = NewCash;
            foreach (Factory f in Factories)
            {
                f.UpdateAvailableCash(NewCash);
            }
        }

        public int getCash()
        {
            return Cash;
        }

        // --------------------------- LOAD EVENT -----------------------
        void SurfaceWindow1_Loaded(object sender, RoutedEventArgs e)
        {
            Targets.Add(new Target(UI, new Point(200, 200)));
            Targets.Add(new Target(UI, new Point(200, 300)));
            Targets.Add(new Target(UI, new Point(this.Width - 200, this.Height - 200)));

            Factories.Add(new Factory(UI, new Point(500, this.Height - 10), 0, Cash));
            Factories.Add(new Factory(UI, new Point(500, 10), 2, Cash));
        }

        // --------------------------- CONTACT UP/DOWN/ETC -----------------------
        private Dictionary<Contact, Unit> Selections = new Dictionary<Contact,Unit>();
        void SurfaceWindow1_ContactChanged(object sender, ContactEventArgs e)
        {
            if (Selections.ContainsKey(e.Contact))
            {
                Selections[e.Contact].AddMarker(e.GetPosition(UI));
            }
        }
        void SurfaceWindow1_ContactDown(object sender, ContactEventArgs e)
        {
            Point p = e.Contact.GetPosition(UI);
            foreach (Factory f in Factories)
            {
                if (f.HitTest(p))
                {
                    // Build a new unit
                    f.BuildUnit(Units, ref Cash);
                    UpdateCash(Cash);
                    return;
                }
            }

            if (U.GetUnitAt(p, Units, true) != null)
            {
                Unit u = U.GetUnitAt(p, Units, true);
                Selections.Add(e.Contact, u);
                u.ResetMarkers();
                return;
            }

        }

        void SurfaceWindow1_ContactUp(object sender, ContactEventArgs e)
        {
            if (Selections.ContainsKey(e.Contact))
            {
                Selections[e.Contact].CommitMarkers();
                Selections.Remove(e.Contact);
            }
        }

        // --------------------------- DEFAULT WPF EVENTS AND STUFF -----------------------
        /// <summary>
        /// Occurs when the window is about to close. 
        /// </summary>
        /// <param name="e"></param>
        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);

            // Remove handlers for Application activation events
            RemoveActivationHandlers();
        }

        /// <summary>
        /// Adds handlers for Application activation events.
        /// </summary>
        private void AddActivationHandlers()
        {
            // Subscribe to surface application activation events
            ApplicationLauncher.ApplicationActivated += OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed += OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated += OnApplicationDeactivated;
        }

        /// <summary>
        /// Removes handlers for Application activation events.
        /// </summary>
        private void RemoveActivationHandlers()
        {
            // Unsubscribe from surface application activation events
            ApplicationLauncher.ApplicationActivated -= OnApplicationActivated;
            ApplicationLauncher.ApplicationPreviewed -= OnApplicationPreviewed;
            ApplicationLauncher.ApplicationDeactivated -= OnApplicationDeactivated;
        }

        /// <summary>
        /// This is called when application has been activated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationActivated(object sender, EventArgs e)
        {
            //TODO: enable audio, animations here
        }

        /// <summary>
        /// This is called when application is in preview mode.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationPreviewed(object sender, EventArgs e)
        {
            //TODO: Disable audio here if it is enabled

            //TODO: optionally enable animations here
        }

        /// <summary>
        ///  This is called when application has been deactivated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnApplicationDeactivated(object sender, EventArgs e)
        {
            //TODO: disable audio, animations here
        }
    }
}